package com.xhui.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhui.reggie.utils.CommonConstant;
import com.xhui.reggie.common.CustomException;
import com.xhui.reggie.dto.SetmealDto;
import com.xhui.reggie.entity.Dish;
import com.xhui.reggie.entity.Setmeal;
import com.xhui.reggie.entity.SetmealDish;
import com.xhui.reggie.mapper.SetmealMapper;
import com.xhui.reggie.service.DishService;
import com.xhui.reggie.service.SetmealDishService;
import com.xhui.reggie.service.SetmealService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

    @Resource
    private DishService dishService;
    @Resource
    private SetmealDishService setmealDishService;

    /**
     *  新增套餐，同时需要保存套餐和菜品的关联关系
     * @param setmealDto 套餐菜品信息
     */
    @Override
    @Transactional // 涉及到多表增加，需具备事务性
    public void saveWithDish(SetmealDto setmealDto) {
        //1. 保存套餐的基本信息，--> setmeal
        // setmealDto 被插入前，其id会有MP中的雪花算法生成，然后在进行数据库的新增
        System.out.println("setmealDto = " + setmealDto);
        this.save(setmealDto);
        //2. 保存套餐和菜品的关联信息 --> setmeal_dish
        List<SetmealDish> dishes = setmealDto.getSetmealDishes();
        // 注意：dishes中需要设置setmealId的值
        dishes.stream().forEach( dish ->{

            dish.setSetmealId(setmealDto.getId());
        });
        setmealDishService.saveBatch(dishes);
    }

    /**
     * 删除若干个套餐(一个或多个) 还需要删除套餐和菜品的关联数据
     * @param ids 套餐ids
     */
    @Override
    @Transactional
    public void removeWithDish(List<Long> ids) {
        if(ids.size() == 0){
            return ;
        }
        // select count(*) from setmeal id in (1, 2, 3) where status = 1
        // 查询套餐的状态，确定是否可用删除
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        // 是否在这个范围内
        wrapper.in(Setmeal::getId, ids);
        // 等值查询，是否相等
        wrapper.eq(Setmeal::getStatus, 1);

        int count = this.count(wrapper);
        if(count > 0){
            // 若不能删除，抛出一个业务异常
            // 要删除的套餐存在起售状态，不能删除
            throw new CustomException("套餐正在售卖中，不能删除");
        }
        // 可以删除，先删除套餐表中的数据 --setmeal
        this.removeByIds(ids);
        // 然后删除套餐中的详细数据 --setmeal_dish中的数据
        LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // delete from setmeal_dish where setmeal_id in (1, 2, 3)
        setmealDishLambdaQueryWrapper.in(SetmealDish::getSetmealId, ids);
        setmealDishService.remove(setmealDishLambdaQueryWrapper);
    }

    /**
     *
     * @param status
     * @param ids
     */
    @Override
    @Transactional
    public void updateStatus(Integer status, List<Long> ids) {

        LambdaUpdateWrapper<Setmeal> setmealLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        setmealLambdaUpdateWrapper.set(Setmeal::getStatus, status);// 待修改的状态
        setmealLambdaUpdateWrapper.in(Setmeal::getId, ids);
        // 1.套餐需要停售，所属菜品均需要处于停售状态吗？ 感觉应该是not
        if(status == 0){
            this.update(setmealLambdaUpdateWrapper);
            return ;
        }
        // 2.套餐需要起售，所属菜品 均不能处于停售
        // 判断 setmeal_dish 中的 进行起售的套餐中的 菜品是不能存在任意一个 是被禁用的
        LambdaQueryWrapper<SetmealDish> setmealDishWrapper = new LambdaQueryWrapper<>();
        setmealDishWrapper.in(SetmealDish::getSetmealId, ids);
        List<SetmealDish> setmealDishes = setmealDishService.list(setmealDishWrapper);

        List<Long> dishIds = new ArrayList<>();
        for (int i = 0; i < setmealDishes.size(); i++) {
            Long dishId = setmealDishes.get(i).getDishId();
            dishIds.add(dishId);
        }

        LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishLambdaQueryWrapper.in(Dish::getId, dishIds);
        dishLambdaQueryWrapper.eq(Dish::getStatus, CommonConstant.STATUS_STOP);
        int count = dishService.count(dishLambdaQueryWrapper);
        // 菜品存在 一个或多个 被禁用
        if(count > 0){
            throw new CustomException("该套餐下存在部分商品被禁用，起售失败");
        }
        // 所属套餐均被启用，可以执行套餐启用
        this.update(setmealLambdaUpdateWrapper);
        System.out.println("count = " + count);
        // dishService.count(dishLambdaQueryWrapper);
        // 停售
    }
}
